home *** CD-ROM | disk | FTP | other *** search
- #include "CArrangeList.h"
-
- void QuickSort(CArrangeList *theList,short left,short right);
- short CompareItems(Ptr aPtr,Ptr bPtr,short aLen,short bLen);
- void DoubleClick(CArrangeList *theList);
-
- extern CursHandle gHandCursor;
-
- void CArrangeList::IArrangeList(CView *theEnclosure,
- CBureaucrat *theSupervisor,short theWidth,short theHeight,
- short theHEncl,short theVEncl,Boolean hasHoriz,Boolean hasVert,
- Boolean hasSizeBox,short theRows,short theRowWidth,short theRowHeight,
- ShortFunc theCompareProc,VoidFunc theDoubleProc)
- {
- register short i;
- Rect theRect;
-
- itsSupervisor = theSupervisor;
- itsScrollPane = new(CScrollPane);
- itsScrollPane->IScrollPane(theEnclosure,this,theWidth,theHeight,
- theHEncl,theVEncl,sizFIXEDSTICKY,sizFIXEDSTICKY,hasHoriz,hasVert,
- hasSizeBox);
-
- if (hasVert)
- theWidth -= 15;
- if (hasHoriz)
- theHeight -= 15;
- itsPanorama = new(CListPanorama);
- itsPanorama->IPanorama(itsScrollPane,this,theWidth-2,theHeight-2,
- 1,1,sizFIXEDLEFT,sizFIXEDTOP);
- itsPanorama->wantsClicks = true;
- itsPanorama->SetScales(theRowWidth,theRowHeight);
- SetRect(&theRect,0,0,1,theRows);
- itsPanorama->SetBounds(&theRect);
- itsScrollPane->InstallPanorama(itsPanorama);
-
- hIndent = 3;
- vIndent = 4;
- currentSelection = 1;
-
- rows = theRows;
- rowWidth = theRowWidth;
- rowHeight = theRowHeight;
-
- itsOrder = (LongHandle)NewHandleClear((long)(rows * 4));
- for (i = 0; i < rows; i ++)
- (*itsOrder)[i] = i;
- itsItems = NewHandleClear(1L);
- itemOffsets = (LongHandle)NewHandleClear((long)((rows + 1) * 4));
- dirty = true;
- clickTime = 0L;
- clickRow = 0;
- if (!theCompareProc)
- compareProc = CompareItems;
- else
- compareProc = theCompareProc;
-
- if (!theDoubleProc)
- doubleProc = DoubleClick;
- else
- doubleProc = theDoubleProc;
- }
-
- void CArrangeList::Dispose()
- {
- DisposHandle(itsOrder);
- DisposHandle(itsItems);
- DisposHandle(itemOffsets);
-
- itsPanorama->Dispose();
- itsScrollPane->Dispose();
-
- inherited::Dispose();
- }
-
- void CArrangeList::GetIndents(short *theHIndent,short *theVIndent)
- {
- *theHIndent = hIndent;
- *theVIndent = vIndent;
- }
-
- void CArrangeList::GetRowCount(short *rowCount)
- {
- *rowCount = rows;
- }
-
- void CArrangeList::GetRowDimensions(short *theWidth,short *theHeight)
- {
- *theWidth = rowWidth;
- *theHeight = rowHeight;
- }
-
- void CArrangeList::GetSelection(short *theSelection)
- {
- *theSelection = currentSelection;
- }
-
- Boolean CArrangeList::IsDirty()
- {
- return dirty;
- }
-
- void CArrangeList::SetIndents(short theHIndent,short theVIndent,
- Boolean redraw)
- {
- hIndent = theHIndent;
- vIndent = theVIndent;
- if (redraw)
- Draw();
- }
-
- void CArrangeList::SetRowDimensions(short theWidth,short theHeight,
- Boolean redraw)
- {
- rowWidth = theWidth;
- rowHeight = theHeight;
- if (redraw)
- Draw();
- }
-
- void CArrangeList::SetSelection(short theSelection)
- {
- InvertRow(currentSelection);
- currentSelection = theSelection;
- InvertRow(currentSelection);
- }
-
- void CArrangeList::SetDirty(Boolean isDirty)
- {
- dirty = isDirty;
- }
-
- void CArrangeList::SetCompareProc(ShortFunc theFunc)
- {
- compareProc = theFunc;
- }
-
- void CArrangeList::SetDoubleProc(VoidFunc theFunc)
- {
- doubleProc = theFunc;
- }
-
- void CArrangeList::AddRow(short count,short rowNum,Boolean redraw)
- {
- Size itemSize;
- register short i;
- Rect frameRect;
-
- itemSize = GetHandleSize(itemOffsets);
- SetHandleSize(itemOffsets,itemSize+(long)(count * 4));
- itemSize = GetHandleSize(itsOrder);
- SetHandleSize(itsOrder,itemSize+(long)(count * 4));
- if (ValidRow(rowNum))
- { BlockMove(&(*itsOrder)[rowNum-1],&(*itsOrder)[rowNum+count-1],
- rows * 4);
- }
- for (i = rows + 1; i < rows+count+1; i ++)
- (*itemOffsets)[i] = (*itemOffsets)[i - 1];
- for (i = 0; i < count; i ++)
- (*itsOrder)[i+rowNum-1] = rows + i;
- rows += count;
-
- itsPanorama->bounds.bottom += count;
- if (redraw)
- { itsScrollPane->AdjustScrollMax();
- itsPanorama->Prepare();
- frameRect = itsPanorama->frame;
- frameRect.top = rowHeight * (rowNum - 1) + 1;
- EraseRect(&frameRect);
- for (i = rowNum; i <= rows; i ++)
- DrawRow(i);
- InvertRow(currentSelection);
- }
- itsScrollPane->itsEnclosure->Prepare();
- }
-
- void CArrangeList::DeleteRow(short count,short rowNum,Boolean redraw)
- {
- register short i,j;
- long rowOffset,nextOffset,size,totalSize;
- register theOrder;
- Size handleSize;
- Rect frameRect;
-
- for (i = rowNum-1; i < rowNum-1+count; i++)
- { rowOffset = (*itemOffsets)[(*itsOrder)[i]];
- nextOffset = (*itemOffsets)[(*itsOrder)[i]+1];
- size = nextOffset - rowOffset;
- totalSize = (*itemOffsets)[rows];
- BlockMove(&(*itsItems)[nextOffset],&(*itsItems)[rowOffset],
- totalSize - nextOffset);
- handleSize = GetHandleSize(itsItems);
- SetHandleSize(itsItems,handleSize - size);
-
- BlockMove(&(*itemOffsets)[(*itsOrder)[i]+1],
- &(*itemOffsets)[(*itsOrder)[i]],(rows-(*itsOrder)[i]) * 4);
- for (j = (*itsOrder)[i]; j < rows; j ++)
- (*itemOffsets)[j] -= size;
- handleSize = GetHandleSize(itemOffsets);
- SetHandleSize(itemOffsets,handleSize - 4);
-
- theOrder = (*itsOrder)[i];
- BlockMove(&(*itsOrder)[i+1],&(*itsOrder)[i],(rows - i - 1) * 4);
- for (j = 0; j < rows - 1; j ++)
- { if ((*itsOrder)[j] > theOrder)
- (*itsOrder)[j] -= 1;
- }
- handleSize = GetHandleSize(itsOrder);
- SetHandleSize(itsOrder,handleSize - 4);
- rows -= 1;
- }
- itsPanorama->bounds.bottom -= count;
- if (currentSelection > rows)
- currentSelection = rows;
- if (redraw)
- { itsScrollPane->AdjustScrollMax();
- itsPanorama->Prepare();
- frameRect = itsPanorama->frame;
- frameRect.top = rowHeight * (rowNum - 1) + 1;
- EraseRect(&frameRect);
- for (i = rowNum; i <= rows; i ++)
- DrawRow(i);
- InvertRow(currentSelection);
- }
- itsScrollPane->itsEnclosure->Prepare();
- }
-
- void CArrangeList::SetRow(Ptr dataPtr,long dataLen,short rowNum,
- Boolean redraw)
- {
- register short i;
- register LongPtr offsets;
- long rowSize;
- register long delta;
- register long rowOffset;
- register long nextOffset;
- Size itemSize;
-
- if (rowNum > rows)
- return;
-
- offsets = *itemOffsets;
- rowOffset = offsets[rowNum - 1];
- nextOffset = offsets[rowNum];
- rowSize = nextOffset - rowOffset;
- delta = dataLen - rowSize;
- if (delta)
- { for (i = rowNum; i < rows+1; i ++)
- offsets[i] += delta;
-
- itemSize = GetHandleSize(itsItems);
- SetHandleSize(itsItems,itemSize+delta);
- BlockMove(&(*itsItems)[nextOffset],&(*itsItems)[nextOffset+delta],
- itemSize - nextOffset);
- }
- BlockMove(dataPtr,&(*itsItems)[rowOffset],dataLen);
- if (redraw)
- DrawRow(rowNum);
- }
-
- void CArrangeList::DrawRow(register short rowNum)
- {
- long rowSize;
- Ptr rowPtr;
-
- if (ValidRow(rowNum))
- { itsPanorama->Prepare();
- MoveTo(hIndent,rowHeight * rowNum - vIndent);
- rowPtr = GetRowOffset(rowNum);
- rowSize = GetRowSize(rowNum);
-
- DrawText(rowPtr,0,rowSize);
- }
- }
-
- void CArrangeList::InvertRow(register short rowNum)
- {
- Rect theRect;
-
- if (ValidRow(rowNum))
- { itsPanorama->Prepare();
- theRect = itsPanorama->frame;
- theRect.top = rowHeight * (rowNum - 1);
- theRect.bottom = rowHeight * rowNum;
- InvertRect(&theRect);
- }
- }
-
- Boolean CArrangeList::ValidRow(register short rowNum)
- {
- if (rowNum <= rows && rowNum >= 1)
- return true;
- else
- return false;
- }
-
- void CArrangeList::Draw()
- {
- register short i;
- Rect frameRect;
- register short visTop,visBottom;
-
- itsScrollPane->Prepare();
- frameRect = itsPanorama->frame;
- itsPanorama->FrameToEnclR(&frameRect);
- EraseRect(&frameRect);
- InsetRect(&frameRect,-1,-1);
- FrameRect(&frameRect);
- visTop = itsPanorama->aperture.top / rowHeight + 1;
- visBottom = itsPanorama->aperture.bottom / rowHeight;
- for (i = visTop; i <= visBottom; i ++)
- DrawRow(i);
- InvertRow(currentSelection);
- itsScrollPane->itsEnclosure->Prepare();
- }
-
- void CArrangeList::DoClick(Point hitPt,short modifierKeys,long when)
- {
- CArrangeTask *theTask;
- Rect bounds;
- short currItem;
- long hExtent,vExtent;
-
- currItem = hitPt.v / rowHeight + 1;
- if (ValidRow(currItem))
- { if ((when - clickTime) < GetDblTime())
- (*doubleProc)(this);
- clickTime = when;
- clickRow = currItem;
- theTask = new(CArrangeTask);
- theTask->IArrangeTask(this);
- itsPanorama->Prepare();
- itsPanorama->GetPixelExtent(&hExtent,&vExtent);
- SetRect(&bounds,0,0,(short)hExtent,(short)vExtent);
-
- itsPanorama->TrackMouse(theTask,hitPt,&bounds);
- theTask->Dispose();
- }
- else
- { InvertRow(currentSelection);
- currentSelection = 0;
- }
- }
-
- Ptr CArrangeList::GetRowOffset(register short rowNum)
- {
- long rowOffset;
-
- rowOffset = (*itemOffsets)[(*itsOrder)[rowNum-1]];
- return (Ptr)&(*itsItems)[rowOffset];
- }
-
- long CArrangeList::GetRowSize(register short rowNum)
- {
- long rowOffset;
-
- rowOffset = (*itemOffsets)[(*itsOrder)[rowNum-1]];
- return (*itemOffsets)[(*itsOrder)[rowNum-1]+1] - rowOffset;
-
- }
-
- void CArrangeList::Sort(short left,short right)
- {
- if (left != right)
- { QuickSort(this,left,right);
- dirty = true;
- }
- }
-
- Boolean CArrangeList::Search(register Ptr dataPtr,register short dataLen,
- short *theRow)
- {
- register short i;
- register Ptr rowOffset;
- register long rowSize;
-
- for (i = 1; i <= rows; i ++)
- { rowOffset = GetRowOffset(i);
- rowSize = GetRowSize(i);
- if ((*compareProc)(rowOffset,dataPtr,rowSize,dataLen) >= 0)
- { *theRow = i;
- return true;
- }
- }
- return false;
- }
-
- void QuickSort(CArrangeList *theList,short left,short right)
- {
- register short i,j;
- register Ptr x;
- register long length,swap;
-
- i = left;
- j = right;
-
- x = theList->GetRowOffset((left+right)/2+1);
- length = theList->GetRowSize((left+right)/2+1);
-
- do
- { while ((*theList->compareProc)(theList->GetRowOffset(i+1),x,
- theList->GetRowSize(i+1),length) < 0 &&
- i < right)
- i ++;
- while ((*theList->compareProc)(x,theList->GetRowOffset(j+1),length,
- theList->GetRowSize(j+1)) < 0 &&
- j > left)
- j --;
- if (i <= j)
- { swap = (*theList->itsOrder)[i];
- (*theList->itsOrder)[i] = (*theList->itsOrder)[j];
- (*theList->itsOrder)[j] = swap;
- i ++;
- j --;
- }
- }
- while (i <= j);
-
- if (left < j)
- QuickSort(theList,left,j);
- if (i < right)
- QuickSort(theList,i,right);
- }
-
- short CompareItems(Ptr aPtr,Ptr bPtr,short aLen,short bLen)
- {
- IUMagString(aPtr,bPtr,aLen,bLen);
- }
-
- void DoubleClick(CArrangeList *theList)
- {
- SysBeep(10);
- }
-
- void CArrangeTask::IArrangeTask(CArrangeList *theList)
- {
- inherited::IMouseTask(0);
-
- itsList = theList;
- lastItem = theList->currentSelection;
- arranging = false;
- }
-
- void CArrangeTask::BeginTracking(Point *startPt)
- {
- short currItem;
- register short rowHeight;
-
- rowHeight = itsList->rowHeight;
- currItem = startPt->v / rowHeight + 1;
- currItem = Max(currItem,1);
- currItem = Min(currItem,itsList->rows);
- if (lastItem != currItem)
- { itsList->InvertRow(lastItem);
- itsList->InvertRow(currItem);
- lastItem = currItem;
- }
- }
-
- void CArrangeTask::KeepTracking(Point *currPt,Point *prevPt,Point *startPt)
- {
- register LongPtr theOrder;
- register short currItem,tempItem,i;
- long swap;
- Rect theRect;
- short rowHeight;
- long vPos;
- short vSpan;
-
- rowHeight = itsList->rowHeight;
- currItem = currPt->v / rowHeight + 1;
-
- currItem = Max(currItem,1);
- currItem = Min(currItem,itsList->rows);
-
- if (itsList->itsPanorama->AutoScroll(*currPt))
- { vPos = itsList->itsPanorama->position.v;
- vSpan = itsList->itsPanorama->height /
- itsList->itsPanorama->vScale;
- currItem = Min(currItem,vPos+vSpan);
- currItem = Max(currItem,vPos+1);
- }
- if (currItem != lastItem)
- { if (!arranging)
- { SetCursor(*gHandCursor);
- arranging = true;
- }
- itsList->InvertRow(lastItem);
- theOrder = *itsList->itsOrder;
-
- if (currItem < lastItem)
- { tempItem = lastItem;
- do
- { tempItem -= 1;
- swap = theOrder[tempItem-1];
- theOrder[tempItem-1] = theOrder[tempItem];
- theOrder[tempItem] = swap;
- }
- while (tempItem != currItem);
- }
- else
- { tempItem = lastItem;
- do
- { swap = theOrder[tempItem-1];
- theOrder[tempItem-1] = theOrder[tempItem];
- theOrder[tempItem] = swap;
- tempItem += 1;
- }
- while (tempItem != currItem);
- }
-
- theRect = itsList->itsPanorama->frame;
- if (currItem < lastItem)
- { theRect.top = rowHeight * (currItem - 1);
- theRect.bottom = rowHeight * lastItem;
- EraseRect(&theRect);
- for (i = currItem; i <= lastItem; i++)
- itsList->DrawRow(i);
- itsList->InvertRow(currItem);
- }
- else
- { theRect.top = rowHeight * (lastItem - 1);
- theRect.bottom = rowHeight * currItem;
- EraseRect(&theRect);
- for (i = lastItem; i <= currItem; i++)
- itsList->DrawRow(i);
- itsList->InvertRow(currItem);
- }
-
- lastItem = currItem;
- itsList->dirty = true;
- }
- }
-
- void CArrangeTask::EndTracking(Point *currPt,Point *prevPt,Point *startPt)
- {
- itsList->currentSelection = lastItem;
- SetCursor(&arrow);
- }
-
- void CListPanorama::Draw(Rect *area)
- {
- ((CArrangeList *)itsSupervisor)->Draw();
- }
-
- void CListPanorama::DoClick(Point hitPt,short modifierKeys,long when)
- {
- ((CArrangeList *)itsSupervisor)->DoClick(hitPt,modifierKeys,when);
- itsScrollPane->itsEnclosure->Prepare();
- }